﻿using Microsoft.AspNetCore.Mvc;
using PMS.Core.Configuration.CommonEnumConfigs;
using PMS.Core.Infrastructure;
using PMS.Services.Authentication.Externel;
using PMS.Services.EntityServices.Customers;
using PMS.Services.SharedKernel;
using PMS.Web.Factories.Customers;
using PMS.Web.Factories.ExternalAuthentication;
using PMS.Web.Factories.SystemModules;
using PMS.Web.Framework.Controllers;
using PMS.Web.Framework.Models;
using PMS.Web.Framework.Mvc.Filters;
using PMS.Web.Models.Customers;
using PMS.Web.Models.Medias;
using System.Linq;

namespace PMS.Web.Controllers.Backend.CustomerManage
{
    public class CustomerManageController : BaseAdminController
    {
        #region Fields
        private readonly ICustomerService _customerService;
        private readonly ICustomerModelFactory _customerModelFactory;
        private readonly ISystemModuleModleFactory _systemModuleFactory;
        private readonly IExternalAuthenticationService _externalAuthenticationService;
        private readonly IExternalAuthenticationModelFactory _externalAuthenticationModelFactory;
        #endregion

        #region Ctor
        public CustomerManageController(ICustomerService customerService,
            ICustomerModelFactory customerModelFactory,
            ISystemModuleModleFactory systemModuleModleFactory,
            IExternalAuthenticationService externalAuthenticationService,
            IExternalAuthenticationModelFactory externalAuthenticationModelFactory)
        {
            _customerService = customerService;
            _customerModelFactory = customerModelFactory;
            _systemModuleFactory = systemModuleModleFactory;
            _externalAuthenticationService = externalAuthenticationService;
            _externalAuthenticationModelFactory = externalAuthenticationModelFactory;
        }
        #endregion

        #region Methods
        /// <summary>
        /// 系统用户管理
        /// </summary>
        /// <returns></returns>
        [ModulePermission]
        public virtual IActionResult CustomerListView(string hashId)
        {
            int moduleId = DecodeId(hashId);
            var model = _systemModuleFactory.GetSystemModuleModel(moduleId);
            ViewBag.ModuleId = model.Id;
            ViewBag.PageTitle = model.DisplayName;
            ViewBag.BodyHtmlClass = "pear-container";
            //prepare model
            var searchModel = _customerModelFactory.PrepareCustomerSearchModel(new CustomerSearchModel(), RoleType.BackendUser);
            searchModel.AvailableCustomerRoles?.Add(new XMSelectListItem()
            {
                Text = "未激活用户",
                Value = "0",
                Selected = false
            });
            searchModel.AvailableCustomerRoles.ToList()
                .Sort((x, y) => {//Value represent to CustomerRoleId
                    int.TryParse(x.Value, out int xId);
                    int.TryParse(y.Value, out int yId);
                    return xId.CompareTo(yId);
                });
            ViewBag.SearchModel = searchModel;
            var viewModel = _customerModelFactory.PrepareCustomerModel(new CustomerModel(), null, true);
            return View(viewModel);
        }

        /// <summary>
        /// 用户管理编辑页
        /// </summary>
        /// <param name="buttonId">按钮权限验证参数：点击按钮Id</param>
        /// <param name="moduleId">按钮权限验证参数：按钮所在系统模块Id</param>
        /// <param name="customerId">用户Id, 0则为新增数据</param>
        /// <returns></returns>
        [ButtonPermission]
        public virtual IActionResult CustomerEditView(int buttonId, int moduleId, int? customerId)
        {
            ViewBag.PageTitle = "用户管理";
            int cid = customerId.HasValue ? customerId.Value : default(int);
            //try to get a customer with the specified id
            var customer = _customerService.GetCustomerById(cid);
            CustomerModel model = null;
            if (customer == null || customer.IsDeleted)
                model = new CustomerModel();

            model = _customerModelFactory.PrepareCustomerModel(model, customer);
            //Prepare SearchModel for customer-related-emails
            ViewBag.CustomerEmailSearchModel = _customerModelFactory.PrepareCustomerEmailSearchModel(customer);
             
            return View(model);
        }

        /// <summary>
        /// 用户管理-用户角色分配页
        /// </summary>
        /// <param name="buttonId">按钮权限验证参数：点击按钮Id</param>
        /// <param name="moduleId">按钮权限验证参数：按钮所在系统模块Id</param>
        /// <param name="customerId">用户Id, 0则为新增数据</param>
        /// <returns></returns>
        [ButtonPermission]
        public virtual IActionResult CustomerAssignRoleView(int buttonId, int moduleId, int customerId)
        {
            ViewBag.BodyHtmlClass = "pear-container";
            //try to get a customer with the specified id
            var customer = _customerService.GetCustomerById(customerId);
            if (customer == null || customer.IsDeleted)
                return new RedirectToActionResult("ErrorPage", "Common", new { errmsg = "指定用户不存在或已被注销" }, false);

            CustomerModel model = _customerModelFactory.PrepareCustomerModel(null, customer);

            return View(model);
        }

        /// <summary>
        /// 在线用户管理页
        /// </summary>
        /// <param name="hashId"></param>
        /// <returns></returns>
        [ModulePermission]
        public virtual IActionResult OnLineCustomerListView(string hashId)
        {
            int moduleId = DecodeId(hashId);
            var model = _systemModuleFactory.GetSystemModuleModel(moduleId);
            ViewBag.ModuleId = model.Id;
            ViewBag.PageTitle = model.DisplayName;
            ViewBag.BodyHtmlClass = "pear-container";
            //prepare model
            ViewBag.SearchModel =  _customerModelFactory.PrepareOnlineCustomerSearchModel(new OnlineCustomerSearchModel());
            var viewModel = new OnlineCustomerModel();
            return View(viewModel);
        }

        /// <summary>
        /// 后台用户个人资料编辑
        /// </summary>
        /// <returns></returns>
        [AuthorizeCustomer(CustomerAuthorizeType.Admin)]
        public virtual IActionResult CustomerProfile()
        {
            ViewBag.BodyHtmlClass = "pear-container";
            var workContext = EngineContext.Current.Resolve<IWorkContext>();
            var customer = workContext.CurrentCustomer;
            if (customer == null || customer.IsDeleted)
                return new RedirectToActionResult("ErrorPage", "Common", new { errmsg = "指定用户不存在或已被注销" }, false);

            CustomerModel model = _customerModelFactory.PrepareCustomerModel(null, customer);

            ViewBag.AllExternalRecords = _externalAuthenticationService.GetCustomerExternalAuthenticationRecords(customer);
            ViewBag.ExternalAuthenticationMethodModel = _externalAuthenticationModelFactory.PrepareExternalMethodsModel();

            //上传头像的对象封装
            ViewBag.AvatarUploadModel = new MediaUploadRequsetModel
            {
                Id = model.AvatarImage.Id,
                Title = $"用户{model.NickName}的头像图片",
                ImageLink = string.Empty,
                Description = string.Empty,
                File = null,
                Useage = nameof(MediaFileUseage.Avatar)
            };
            return View(model);
        }

        /// <summary>
        /// 后台用户资料更换/绑定登录账号(包含邮箱/手机号/登录账号)
        /// 不论新绑定还是修改绑定账号，都只向修改的新账号发送 短信/邮件验证码
        /// </summary>
        /// <returns></returns>
        [AuthorizeCustomer(CustomerAuthorizeType.Admin)]
        public virtual IActionResult ChangeCustomerAccount(AccountBindMode mode = AccountBindMode.MobilePhone)
        {
            ViewBag.BodyHtmlClass = "pear-container";
            var workContext = EngineContext.Current.Resolve<IWorkContext>();
            var customer = workContext.CurrentCustomer;
            if (customer == null || customer.IsDeleted)
                return new RedirectToActionResult("ErrorPage", "Common", new { errmsg = "指定用户不存在或已被注销" }, false);

            var BindAccountModel = new BindAccountModel
            {
                Id = customer.Id,
                Mobile = (mode == AccountBindMode.MobilePhone || mode == AccountBindMode.LoginName) ? customer.Mobile : string.Empty,
                Email = mode == AccountBindMode.Email ? customer.Email : string.Empty,
                LoginName = mode == AccountBindMode.LoginName ? customer.LoginName : string.Empty,
                DisplayCaptcha = true,
                BindMode = mode
            };
            return View(BindAccountModel);
        }
        #endregion
    }
}
